
#include <stdio.h>
#include <aos/kernel.h>
// #include <csky_common.h>
// #include "drv_isp.h"
#include <pin.h>
#include "drv_gpio.h"   
#include "pin_name.h" 
// // #include <csi_config.h>
//#include "cam_engine_api.h"
//#include "cam_engine_aaa_api.h"
// #include "hal/hal_api.h" 
#include "ulog/ulog.h"
#include "aos/hal/i2c.h"
// #include "aos/hal/mipi_csi.h"
#include "camera_config.h"
// #include "mm_config.h"
// #include "drv_isp.h"
//#include "usbddemo.h"
//#include "cam_engine_ctrl.h"
//#include "image_proc.h"
//#include "wrapper.h"
#include "image_task.h"

extern volatile uint8_t cb0_transfer_flag;
extern volatile uint8_t cb1_transfer_flag;
extern volatile uint8_t cb2_transfer_flag;

extern void mdelay(uint32_t ms);
extern void udelay(uint32_t us);
extern int hal_i2c_master_write(i2c_dev_t *i2c, uint8_t slave_addr, uint16_t reg_offs, int offs_len, const uint8_t *data, int size);
extern int hal_i2c_master_read(i2c_dev_t *i2c, uint8_t slave_addr, uint16_t reg_offs, int offs_len, const uint8_t *data, int size);
int32_t iic_write(i2c_dev_t *i2c, uint16_t reg, uint8_t val)
{
    int32_t ret = 0;
    // uint8_t data[3] = { reg >> 8, reg & 0xff, val};
    //printf("[IIC_write]:port %d,devAddr %x,handle %x \n",i2c->port,i2c->config.dev_addr,i2c->priv);

#if 0
 	ret = hal_i2c_master_send_for_configurate(i2c,i2c->config.dev_addr,data,3, 1);
#else
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_write(i2c,i2c->config.dev_addr, reg, 2, &val, 1);
    //aos_mutex_unlock(&i2c->mutex_port);
#endif 

     if (ret < 0) {
        printf("[sensor_write]:Send error:%d.\n",ret);
        return -1;
    }
    
    return ret;
}

int32_t iic_write_r8_d8(i2c_dev_t *i2c, uint8_t reg, uint8_t val)
{
    int32_t ret = 0;
    // uint8_t data[2] = { reg & 0xff, val & 0xff};
#if 0
//	ret = hal_i2c_master_send(i2c,i2c->config.dev_addr,data,2, 1);
	ret = hal_i2c_master_send_for_configurate(i2c,i2c->config.dev_addr,data,2, 1);
#else 
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_write(i2c, i2c->config.dev_addr, reg, 1, &val, 1);
    //aos_mutex_unlock(&i2c->mutex_port);
#endif 

    if (ret < 0) {
        printf("[sensor_write]:Send ar0230_write:%d.\n",ret);
        return -1;
    }
    
    return ret;
}


int32_t iic_write16bit(i2c_dev_t *i2c, uint16_t reg, uint16_t val)
{
    int32_t ret = 0;
    uint8_t data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff};

#if 0
	ret = hal_i2c_master_send(i2c,i2c->config.dev_addr,data,4, 1);
#else 
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_write(i2c, i2c->config.dev_addr, reg, 2, &data[2], 2);
    //aos_mutex_unlock(&i2c->mutex_port);
#endif 		
    if (ret < 0) {
        printf("[sensor_write]:Send ar0230_write:%d.\n",ret);
        return -1;
    }
    
    return ret;
}

int32_t iic_write_r16_d16(i2c_dev_t *i2c, uint16_t reg, uint16_t val)
{
    int32_t ret = 0;
    uint8_t data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff};

#if 0
	ret = hal_i2c_master_send(i2c,i2c->config.dev_addr,data,4, 1);
#else 
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_write(i2c, i2c->config.dev_addr, reg, 2, &data[2], 2);
    //aos_mutex_unlock(&i2c->mutex_port);
#endif 		
    if (ret < 0) {
        printf("[sensor_write]:Send ar0230_write:%d.\n",ret);
        return -1;
    }
    
    return ret;
}


int32_t iic_read(i2c_dev_t *i2c, uint16_t reg, uint8_t *read_data)
{
    int ret = 0;
    // uint8_t data_w[2] = { reg >> 8, reg & 0xff };
#if 0
    ret = hal_i2c_master_send(i2c,i2c->config.dev_addr,data_w,2, 1);
    if (ret < 0) {
        printf("[sensor_read]:Send error:%d.\n",ret);
        return -1;
    }

    /* wait for camera to prepare data */
//    mdelay(1);

    ret = hal_i2c_master_recv(i2c,i2c->config.dev_addr, read_data,1,1);
    if (ret < 0) {
    	printf("[sensor_read]:receive error %d.\n",ret);
        return -1;
    }
#else 

    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_read(i2c, i2c->config.dev_addr, reg, 2, read_data, 1);
    //aos_mutex_unlock(&i2c->mutex_port);
	if (ret < 0) {
		printf("I2C : reveive error!\n");
		return -1;
	}

	
#endif 

    return ret;
}

int32_t iic_read_r8_d8(i2c_dev_t *i2c, uint8_t reg, uint8_t *read_data)
{
    int ret = 0;
    // uint8_t data_w[1] = {reg & 0xff };
#if 0
    ret = hal_i2c_master_send(i2c, i2c->config.dev_addr, data_w, 1, 1);
    if (ret < 0) {
        printf("[sensor_read]:Send error:%d.\n",ret);
        return -1;
    }

    /* wait for camera to prepare data */
    mdelay(5);

    ret = hal_i2c_master_recv(i2c,i2c->config.dev_addr, read_data,1,1);
    if (ret < 0) {
    	printf("[sensor_read]:receive error %d.\n",ret);
        return -1;
    }
#else 
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_read(i2c, i2c->config.dev_addr, reg, 1, read_data, 1);
    //aos_mutex_unlock(&i2c->mutex_port);
#endif 

    return ret;
}


int32_t iic_read16bit(i2c_dev_t *i2c, uint16_t reg, uint8_t *read_data)
{
    int ret = 0;
    // uint8_t data_w[2] = { reg >> 8, reg & 0xff };
#if 0
    ret = hal_i2c_master_send(i2c, i2c->config.dev_addr, data_w, 2, 1);
    if (ret < 0) {
        printf("[sensor_read]:Send error:%d.\n", ret);
        return -1;
    }

    /* wait for camera to prepare data */
    mdelay(5);

    ret = hal_i2c_master_recv(i2c, i2c->config.dev_addr, read_data, 2, 1);
    if (ret < 0) {
    	printf("[sensor_read]:receive error %d.\n",ret);
        return -1;
    }
#else 
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_read(i2c, i2c->config.dev_addr, reg, 2, read_data, 1);
    //aos_mutex_unlock(&i2c->mutex_port);
	
#endif 

    return ret;
}

int32_t iic_read_r16_d16(i2c_dev_t *i2c, uint16_t reg, uint8_t *read_data)
{
    int ret = 0;
    // uint8_t data_w[2] = { reg >> 8, reg & 0xff };
#if 0
    ret = hal_i2c_master_send(i2c, i2c->config.dev_addr, data_w, 2, 1);
    if (ret < 0) {
        printf("[sensor_read]:Send error:%d.\n", ret);
        return -1;
    }

    /* wait for camera to prepare data */
    mdelay(5);

    ret = hal_i2c_master_recv(i2c, i2c->config.dev_addr, read_data, 2, 1);
    if (ret < 0) {
    	printf("[sensor_read]:receive error %d.\n",ret);
        return -1;
    }
#else 
    //aos_mutex_lock(&i2c->mutex_port, 100);
	ret = hal_i2c_master_read(i2c, i2c->config.dev_addr, reg, 2, read_data, 2);
    //aos_mutex_unlock(&i2c->mutex_port);
	
#endif 

    return ret;
}



int32_t iic_write_array(i2c_dev_t *i2c, regval_list *regs, uint32_t array_size)
{
    int32_t i = 0, ret;
	//printf("%s >>>>  %d \n",__func__, __LINE__);
    if(!regs)
        return -EINVAL;
    while(i < array_size) {
        ret = iic_write(i2c, regs->addr, regs->data);
        if (ret < 0)
            return -1;
        i++;
        regs++;
    }

    return 0;
}

int32_t iic_write_array_r8_d8(i2c_dev_t *i2c, regval_list *regs, uint32_t array_size)
{
    int32_t i = 0, ret;
    if(!regs)
        return -EINVAL;
    while(i < array_size) {
        ret = iic_write_r8_d8(i2c, regs->addr, regs->data);
        if (ret < 0)
            return -1;
        i++;
        regs++;
    }

    return 0;
}


int32_t iic_write16bit_array(i2c_dev_t *i2c, regval_list *regs, uint32_t array_size)
{
    int32_t i = 0, ret;
    if(!regs)
        return -EINVAL;
    while(i < array_size) {
        ret = iic_write16bit(i2c, regs->addr, regs->data);
        if (ret < 0)
            return -1;
        i++;
        regs++;
    }

    return 0;
}


int32_t iic_read_array(i2c_dev_t *i2c, regval_list *regs, uint32_t array_size)
{
    int32_t i = 0, ret;

    if(!regs)
        return -EINVAL;
    while(i < array_size) {
        ret = iic_read(i2c,regs->addr, (uint8_t *)&regs->data);
        if (ret < 0) {
            return -1;
        } else {
            //PRINTF_LOG("adr 0x%04x,data 0x%02x \n",regs->addr,regs->data);
			//printf("adr 0x%04x,data 0x%02x \n",regs->addr,regs->data);
        }
        i++;
        regs++;
    }

    return 0;
}

int32_t iic_read16bit_array(i2c_dev_t *i2c, regval_list *regs, uint32_t array_size)
{
    int32_t i = 0, ret;
    uint8_t data[2] = {0};

    if(!regs)
        return -EINVAL;
    while(i < array_size) {
        ret = iic_read16bit(i2c,regs->addr, data);
        if (ret < 0) {
            return -1;
        } else {
            PRINTF_LOG("adr : 0x%04x,data : 0x%02x 0x%02x \n",regs->addr,data[0],data[1]);
        }
        i++;
        regs++;
    }

    return 0;
}

int32_t iic_read_array_r8_d8(i2c_dev_t *i2c, regval_list *regs, uint32_t array_size)
{
    int32_t i = 0, ret;
    uint8_t data[2] = {0};

    if(!regs)
        return -EINVAL;
    while(i < array_size) {
        ret = iic_read_r8_d8(i2c,regs->addr, data);
        if (ret < 0) {
            return -1;
        } else {
            //printf("adr : 0x%04x,data : 0x%02x 0x%02x \n",regs->addr,data[0]);
        }
        i++;
        regs++;
    }

    return 0;
}


i2c_dev_t  isp_i2c[CONFIG_IIC_NUM];

int isp_i2c_init(int num, i2c_dev_t *i2c,uint32_t dev_addr)
{
	memcpy(&isp_i2c[num], i2c, sizeof(i2c_dev_t));
    isp_i2c[num].config.dev_addr = dev_addr;
    return 0;
}

//sensor iic pcsi_iic
int I2C_read(uint8_t bus_num, uint16_t slave_addr, uint16_t reg_addr, 
                uint8_t reg_addr_size, uint8_t *data_buf, uint32_t byte_size)
{
    int ret = 0;

	ret = hal_i2c_master_read(&isp_i2c[bus_num], slave_addr, \
								reg_addr, reg_addr_size, data_buf, byte_size);

    return 0;
}


int I2C_write(uint8_t bus_num, uint16_t slave_addr, uint16_t reg_addr, 
                uint8_t reg_addr_size, uint8_t *reg_data, uint32_t byte_size)
{
    int ret = 0;

	ret = hal_i2c_master_write(&isp_i2c[bus_num], slave_addr, \
							reg_addr, reg_addr_size, reg_data, byte_size);

    return 0;
}

